-
Notifications
You must be signed in to change notification settings - Fork 236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFR] Responsive chart #249
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We agreed to implement E2E tests to ensure resizing works, as JSDOM doesn't seem to support clientWidth
property.
src/index.js
Outdated
@@ -73,8 +77,24 @@ export default ({ d3 = window.d3, ...customConfiguration }) => { | |||
.call(draw(config, xScale)); | |||
}; | |||
|
|||
const chart = selection => { | |||
const root = selection.selectAll('svg').data(selection.data()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move these two lines in createChart
src/index.js
Outdated
window.removeEventListener('resize', callback, true); | ||
}; | ||
|
||
const createChart = (root, selection) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initChart
docs/configuration.md
Outdated
@@ -326,3 +326,9 @@ This parameter configures the minimum zoom level available. Set it to a not-null | |||
_Default: Infinity_ | |||
|
|||
This parameter configures the maximum zoom level available. Set it to a lower value to prevent your users from zooming in too deeply. | |||
|
|||
### removeOnResize |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove this configuration parameter. Instead, I would expose a destroy
method taking a callback as argument. Something like:
destroy: callback => {
global.removeEventListener('resize', resizeListener);
callback();
}
src/index.js
Outdated
@@ -12,7 +12,15 @@ import { withinRange } from './withinRange'; | |||
|
|||
// do not export anything else here to keep window.eventDrops as a function | |||
export default ({ d3 = window.d3, ...customConfiguration }) => { | |||
const chart = selection => { | |||
const onResize = callback => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for these functions. Just keep a reference to the event listener to be able to remove it in the destroy
method.
src/index.js
Outdated
chart._removeOnResize = () => removeOnResize(updateChart); | ||
window.addEventListener('resize', updateChart, true); | ||
|
||
chart._removeOnResize = () => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need a function for this single line? :)
docs/configuration.md
Outdated
|
||
_Default: () => {}_ | ||
|
||
Function to be executed when you want to remove [`resize`](https://developer.mozilla.org/en-US/docs/Web/Events/resize) event. | ||
Function to be executed when you want to destroy the chart. By default, it remove `resize` event and execute the callback. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/Function to be executed when you want to destroy the chart. By default, it remove resize
event and execute the callback./Execute this function before to removing the chart from DOM. It prevents some memory leaks due to event listeners./
docs/configuration.md
Outdated
@@ -327,8 +327,8 @@ _Default: Infinity_ | |||
|
|||
This parameter configures the maximum zoom level available. Set it to a lower value to prevent your users from zooming in too deeply. | |||
|
|||
### removeOnResize | |||
### destroy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move it to: https://github.com/marmelab/EventDrops/blob/master/README.md#interface
README.md
Outdated
* **draw(config, scale)** redraw chart using given configuration and `d3.scaleTime` scale | ||
* **scale()** provides the horizontal scale, allowing you to retrieve bounding dates thanks to `.scale().domain()`, | ||
* **filteredData()** returns an object with both `data` and `fullData` keys containing respectively bounds filtered data and full dataset. | ||
* **draw(config, scale)** redraw chart using given configuration and `d3.scaleTime` scale |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/redraw/redraws/
As requested by jpetitcolas at #249 (comment)
README.md
Outdated
* **scale()** provides the horizontal scale, allowing you to retrieve bounding dates thanks to `.scale().domain()`, | ||
* **filteredData()** returns an object with both `data` and `fullData` keys containing respectively bounds filtered data and full dataset. | ||
* **draw(config, scale)** redraw chart using given configuration and `d3.scaleTime` scale | ||
* **destroy** execute this function before to removing the chart from DOM. It prevents some memory leaks due to event listeners. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/execute this function before to removing the chart from DOM/should be executed whenever you remove the chart from DOM/
\_Default: | ||
|
||
```js | ||
const chart = eventDrops({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not the default value. Display default value only here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
docs/configuration.md
Outdated
}, | ||
}); | ||
|
||
This parameter configures the number of ticks display in the header |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this sentence. I propose:
When reducing chart width, we need to display less labels on the horizontal axis to keep a readable chart. This parameter aims to solve the issue. Hence, on smallest devices, it displays only 3 labels by default at the same time.
And add a list of breakpoint resolutions to know what small
means.
src/axis.js
Outdated
import breakpoints from './breakpoints'; | ||
|
||
export const getBreakpointLabel = point => | ||
Object.keys(breakpoints).reduce((accumulator, label) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just using a for
loop? It would prevent browsing every breakpoints for smallest devices.
src/axis.js
Outdated
@@ -44,6 +59,11 @@ export default (d3, config, xScale) => { | |||
.axisTop(xScale) | |||
.tickFormat(d => tickFormat(d, formats, d3)); | |||
|
|||
const breakpoint = getBreakpointLabel(window.innerWidth) || 'extra'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we do it in the resize
event instead? We don't need to recompute it everytime if window size is kept the same.
src/axis.js
Outdated
@@ -44,6 +59,11 @@ export default (d3, config, xScale) => { | |||
.axisTop(xScale) | |||
.tickFormat(d => tickFormat(d, formats, d3)); | |||
|
|||
const breakpoint = getBreakpointLabel(window.innerWidth) || 'extra'; | |||
if (numberDisplayedTicks) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need an if
here, with the default value?
src/axis.spec.js
Outdated
@@ -120,8 +120,37 @@ describe('Axis', () => { | |||
expect(timeFormatDefaultLocaleSpy).toHaveBeenCalledWith(defaultLocale); | |||
}); | |||
|
|||
it('should display tick using configuration locale', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why the locale intervenes here. :)
src/axis.spec.js
Outdated
numberDisplayedTicks: { extra: 9 }, | ||
}; | ||
|
||
axis(d3, config, defaultScale)(selection); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a test
function to not repeat yourself and focus more on what you are testing.
src/breakpoints.js
Outdated
@@ -0,0 +1,6 @@ | |||
export default { | |||
small: 576, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't it be in configuration?
src/index.js
Outdated
const root = selection.selectAll('svg').data(selection.data()); | ||
|
||
root.exit().remove(); | ||
chart._breakpoint = getBreakpointLabel(breakpoints, window.innerWidth); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use global
instead of window
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename to currentBreakpointLabel
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add documentation and a test to ensure we can sill access this attribute.
src/axis.js
Outdated
@@ -1,5 +1,15 @@ | |||
import { timeFormat } from 'd3-time-format'; | |||
|
|||
export const getBreakpointLabel = (breakpoints, point) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move it to index.js
as you use it here. But as rollup requires a single export in this file, we probably need an extra breakpoint.js
file.
README.md
Outdated
@@ -84,9 +84,11 @@ You can either use D3 as a specific import (specifying it in first argument of ` | |||
|
|||
In addition to this configuration object, it also exposes some public methods allowing you to customize your application based on filtered data: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/methods/members/
README.md
Outdated
* **filteredData()** returns an object with both `data` and `fullData` keys containing respectively bounds filtered data and full dataset. | ||
* **draw(config, scale)** redraws chart using given configuration and `d3.scaleTime` scale | ||
* **destroy** execute this function before to removing the chart from DOM. It prevents some memory leaks due to event listeners. | ||
* **currentBreakpointLabel** returns a label of current breakpoint, [list of breakpoints](./docs/configuration.md#breakpoints). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/returns a label of current breakpoint, [list of breakpoints]/returns current breakpoint (for instance small
) among a [list of breakpoints]/
README.md
Outdated
* **scale()** provides the horizontal scale, allowing you to retrieve bounding dates thanks to `.scale().domain()`, | ||
* **filteredData()** returns an object with both `data` and `fullData` keys containing respectively bounds filtered data and full dataset. | ||
* **draw(config, scale)** redraws chart using given configuration and `d3.scaleTime` scale | ||
* **destroy** execute this function before to removing the chart from DOM. It prevents some memory leaks due to event listeners. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/destroy/destroy()/
As requested by jpetitcolas at #249 (comment)
…s]/returns current breakpoint (for instance `small`) among a [list of breakpoints]/ As requested by jpetitcolas at #249 (comment)
As requested by jpetitcolas at #249 (comment)
As requested by jpetitcolas at marmelab#249 (comment)
As requested by jpetitcolas at marmelab#249 (comment)
…s]/returns current breakpoint (for instance `small`) among a [list of breakpoints]/ As requested by jpetitcolas at marmelab#249 (comment)
As requested by jpetitcolas at marmelab#249 (comment)
Make responsive great again.
Todo review
fixes #245
PS: Test in other PR with cypress